﻿#define MODE_PRO
#undef MODE_PRO

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using DataModel;
using System.Xml;

/*

 * TODO:
 *      [Priority] Seperate Deployer from Solution.
 *      
 *      Check Exit events? Smooth out save prompt when loading files / creating new project.
 *      
 *      Spruce up Excel Report Formating
 *      Add a sheet to the excel report for managed metadata
 *      
 *      Test Deployment thoroughly.
 */

namespace MetaDesigner
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private Dictionary<TermSet, List<TreeViewItem>> tviList = new Dictionary<TermSet, List<TreeViewItem>>();
        private bool changingSiteColumns = false;
        private bool changingContentTypes = false;

        public const bool DEV_MODE_ENABLED = false;

        private delegate void NoArgDelegate();
        
        public MainWindow()
        {
            InitializeComponent();
            Application.Current.MainWindow.Title = SaveFile.WindowTitle;

            #region CREATE SAMPLE DATA BECAUSE TESTING
            if (DEV_MODE_ENABLED) //set to false for further testing, true for quicker testing
            {
                SaveFile.NewFile("Helux dev values", "C:\\test."+DataModel.Names.FileExtension);
                Title = "HELUX DEV MODE";
                ContentTypesTab.IsEnabled = true;
                SiteColumnsTab.IsEnabled = true;
                ManagedMetaDataTab.IsEnabled = true;
                ToggleProjectMenus();
                Group tsGroup = new Group("DEV MODE TERM SET", "sample term set created for testing");
                SaveFile.scGroupsList.Add(tsGroup);
                for (int i = 0; i < 3; i++)
                {
                    TermSet ts = new TermSet("term set" + (i + 1));
                    ts.Group = tsGroup;
                    SaveFile.termSets.Add(ts);
                    for (int j = 0; j < 4; j++)
                    {
                        SaveFile.termSets.ElementAt(i).AddRootTerm("set " + (i + 1) + ", term " + (j + 1));
                        SaveFile.termSets.ElementAt(i).ElementAt(j).IsTaggable = false;
                        Term subTerm = SaveFile.termSets.ElementAt(i).ElementAt(j).Add("WE MUST GO DEEPER![" + i + "~" + j + "]");
                        for (int k = 0; k < 2; k++)
                        {
                            subTerm = subTerm.Add("[" + i + "~" + j + "~" + k + "] we must go deeper");
                            if (subTerm == null)
                            {
                                break;
                            }
                        }
                    }
                }

                SiteColumn sc1 = new SiteColumn(GUID.get(), "col 1", "col 11", SiteColumnType.SINGLE_LINE_OF_TEXT, false, false, "", "", "first test");
                SaveFile.siteCols.Add(sc1);

                SiteColumn sc2 = new SiteColumn(GUID.get(), "col 2", "col 12", SiteColumnType.NUMBER, false, false, "", "", "second test");
                SaveFile.siteCols.Add(sc2);

                SiteColumn sc3 = new SiteColumn(GUID.get(), "col 3", "col 13", SiteColumnType.CHOICE, false, false, "", "", "third, and choice, test");
                sc3.SList.Add("choice 1");
                sc3.SList.Add("choice 2");
                sc3.SList.Add("choice 3");
                SaveFile.siteCols.Add(sc3);

                SiteColumn sc4 = new SiteColumn(GUID.get(), "col 4", "col 14", SiteColumnType.MANAGED_METADATA, false, false, "", "", "fourth for metadata!");
                sc4.Tag = ((Term)((TermSet)SaveFile.termSets.ElementAt(0)).ElementAt(0));
                SaveFile.siteCols.Add(sc4);

                ContentType ct = new ContentType(GUID.get(), "ctype1", "sample type", new List<SiteColumn>(new[]{sc1, sc2, sc3}), ContentType.ROOT_TYPE);
                SaveFile.contentTypes.Add(ct);

                ct = new ContentType(GUID.get(), "ctype2", "sample 2222 type", new List<SiteColumn>(new[] { sc3, sc4, sc1 }), ContentType.ROOT_TYPE);
                SaveFile.contentTypes.Add(ct);
            }            
            #endregion

            UpdateContentTypeList();
            UpdateSiteColumnList();
            ManagedMetaDataTermSetTermTree.IsEnabled = false;
            UpdateManagedMetaDataTermSetList();

            InitLists();

            try
            {
                Microsoft.Office.Interop.Excel.Application excelTest = new Microsoft.Office.Interop.Excel.Application();
                excelTest = null;
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("factory for component"))
                {
                    //Menu_Report.IsEnabled = false; //disabling this makes the tooltip not display... workaround time... :(
                    Menu_Report.Command = null;
                    Menu_Report.Opacity = 0.4;
                    DataModel.Log.Append("Disabling Generate Report menu option because: This feature is disabled because Excel is not installed on this machine.").AppendLine();
                    Menu_Report.ToolTip = "This feature is disabled because Excel is not installed on this machine.";
                }
            }

            try
            {
                SPFetch.Program derp2 = new SPFetch.Program();
                derp2.run("");
            }
            catch (Exception ex)
            {
                if (ex.Message.Contains("assembly"))
                {
                    //Fetch_Menu.IsEnabled = false; //disabling this makes the tooltip not display... workaround time... :(
                    Fetch_Menu.Command = null;
                    Fetch_Menu.Opacity = 0.4;
                    DataModel.Log.Append("Disabling SPFetch menu option because: This feature is disabled because SharePoint is not installed on this machine.").AppendLine();
                    Fetch_Menu.ToolTip = "This feature is disabled because SharePoint is not installed on this machine.";
                    /*
                    Deploy_Menu.Command = null;
                    Deploy_Menu.Opacity = 0.4;
                    DataModel.Log.Append("Disabling SPDeploy menu option because: This feature is disabled because SharePoint is not installed on this machine.").AppendLine();
                    Deploy_Menu.ToolTip = "This feature is disabled because SharePoint is not installed on this machine.";
                     * */
                }
                if (ex.Message.Contains("32-bit process"))
                {
                    //Fetch_Menu.IsEnabled = false; //disabling this makes the tooltip not display... workaround time... :(
                    Fetch_Menu.Command = null;
                    Fetch_Menu.Opacity = 0.4;
                    DataModel.Log.Append("Disabling SPFetch menu option because: This feature is disabled because this program is a 32-bit build which does not support SharePoint.").AppendLine();
                    Fetch_Menu.ToolTip = "This feature is disabled because this program is a 32-bit build which does not support SharePoint.";

                    /*
                    Deploy_Menu.Command = null;
                    Deploy_Menu.Opacity = 0.4;
                    DataModel.Log.Append("Disabling SPDeploy menu option because: This feature is disabled because this program is a 32-bit build which does not support SharePoint.").AppendLine();
                    Deploy_Menu.ToolTip = "This feature is disabled because this program is a 32-bit build which does not support SharePoint.";
                     * */
                }
            }
        }

        private void InitLists()
        {
            InitializeContentTypeGroupDropdown();
            InitializeSiteColumnTypeDropdown();
            InitializeSiteColumnGroupDropdown();
        }
       
        #region COMMAND BINDINGS
        /*
         * START OF COMMAND BINDINGS
         */
        private void NewCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            New();
        }

        private void OpenCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Open();
        }

        private void SaveCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Save();
        }

        private void SaveAsCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            SaveAs();
        }  

        private void ExitCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            this.Close();
        }

        private void RenameCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            RenameProject();
        }

        private void ReportCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            GenerateReport();
        }

        private void SPFetchBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            try
            {
                SPFetchGUI fetch = new SPFetchGUI();
                fetch.Owner = this;
                fetch.Show();
            }
            catch (Exception ex)
            {
                Log.Append("SPFetchGUI exception: " + ex.Message).AppendLine();
            }
        }

        // to be used for an "integrated version". Now deprecated.
        private void SPDeployBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            Save();
            try
            {
                String s1 = "";
                if (SaveFile.SPDump_SiteUrl != null &&  SaveFile.SPDump_SiteUrl != "default" && SaveFile.SPDump_SiteUrl != "")
                {
                    s1 = SaveFile.SPDump_SiteUrl;
                }

                String s2 = "";
                if (SaveFile.Path != null && SaveFile.Path != "")
                {
                    s2 = SaveFile.Path;
                }
                
                //SPDeployer.MainWindow depWindow = new SPDeployer.MainWindow(s1, s2);
                //depWindow.Owner = this;
                //depWindow.Show();
            }
            catch (Exception ex)
            {
                Log.Append("SPDeployer exception: " + ex.Message).AppendLine();
            }
        }

        private void AddTermSetCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AddTermSet();
        }

        private void RenameTermSetCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            RenameTermSet((TermSet)e.Parameter);
        }
        
        private void DeleteTermSetCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            DeleteTermSet((TermSet)e.Parameter);
        }        

        private void AddRootTermCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AddRootTerm((TermSet)e.Parameter);
        }

        private void AddTermCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AddTerm((Term)e.Parameter);
        }

        private void RenameTermCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            RenameTerm((Term)e.Parameter);
        }

        private void DeleteTermCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            DeleteTerm((Term)e.Parameter);
        }

        private void ToggleTaggableCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ToggleTaggable((Term)e.Parameter);
        }

        private void ExpandAllTreeItemCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ExpandAllTreeItems((TreeViewItem)e.Parameter);
        }

        private void CollapseAllTreeItemCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            CollapseAllTreeItems((TreeViewItem)e.Parameter);
        }

        private void AddSiteColumnCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AddSiteColumn();
        }

        private void RenameSiteColumnCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            RenameSiteColumn((SiteColumn)e.Parameter);
        }

        private void DeleteSiteColumnCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            DeleteSiteColumn((SiteColumn)e.Parameter);
        }

        private void ManageSiteColumnMetadataTagsCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            TermPicker tpWindow = new TermPicker(((TextBox)e.Parameter));
            tpWindow.Owner = this;
            tpWindow.ShowDialog();
        }

        private void PopupSiteColumnMetadataTagsCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            StringBuilder sb = new StringBuilder();
            try
            {
                sb.Append(((TermSet)((TextBox)e.Parameter).Tag).GetChildrenFlat());
            }
            catch (Exception ex)
            {
                Log.Append("PopupSiteColumnMetadataTagsCommandBinding_Executed Exception:").Append(ex.Message).AppendLine();
            }
            TextDisplay tWindow = new TextDisplay("Selected Terms", sb.ToString(), this, "tagIcon");
            tWindow.Owner = this;
            tWindow.ShowDialog();
        }

        private void AddContentTypeCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            AddContentType();
        }
        /*
         * END OF COMMAND BINDINGS
         */
        #endregion
       
        #region EVENT HOOKS
        /*
         * START OF EVENT HOOKS 
         */
        private void AboutClick(object sender, RoutedEventArgs e)
        {
            About aboot = new About();
            aboot.Owner = this;
            aboot.ShowDialog();
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            e.Cancel = true;
            Exit();
        }

        private void Window_Closed(object sender, EventArgs e)
        {
            if (DEV_MODE_ENABLED) { MessageBox.Show(Log.getLog()); }
        }

        private void ShowLog(object sender, RoutedEventArgs e)
        {
            TextDisplay tWindow = new TextDisplay("Error Log", Log.getLog(), this, "bugIcon3");
            tWindow.Show();
        }

        private void ManagedMetaDataTermSetList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            foreach (ListBoxItem s in e.RemovedItems)
            {
                CaptureTVIstates(SaveFile.termSets.GetTermSetByName((String)s.Content));
            }            

            LoadManagedMetaDataTermTree();
            UpdateManaegedMetaDataTermSetButtons();
        }

        private void ManagedMetaDataTermSetButton_Delete_Click(object sender, RoutedEventArgs e)
        {
            String selectedTermSetName = GetSelectedMetadataTermSet();
            DeleteTermSet(SaveFile.termSets.GetTermSetByName(selectedTermSetName));
        }

        private void ManagedMetaDataTermSetButton_Rename_Click(object sender, RoutedEventArgs e)
        {
            String selectedTermSetName = GetSelectedMetadataTermSet();
            RenameTermSet(SaveFile.termSets.GetTermSetByName(selectedTermSetName));
        }

        private void ManagedMetaDataTermSetButton_New_Click(object sender, RoutedEventArgs e)
        {
            AddTermSet();
        }

        private void SiteColumnsList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            changingSiteColumns = true;
            UpdateSiteColumnFields(SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn()));
            changingSiteColumns = false;
        }

        private void SiteColumnsButton_New_Click(object sender, RoutedEventArgs e)
        {
            AddSiteColumn();
        }

        private void SiteColumnsButton_Rename_Click(object sender, RoutedEventArgs e)
        {
            RenameSiteColumn(SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn()));
        }

        private void SiteColumnsButton_Delete_Click(object sender, RoutedEventArgs e)
        {
            DeleteSiteColumn(SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn()));
        }

        private void choiceTextBox_TextInput(object sender, RoutedEventArgs e)
        {
            //StringBuilder msg = new StringBuilder();
            List<String> slist = (List<String>)((TextBox)sender).Tag;
            //msg.Append(slist.Count).Append("->");
            slist.RemoveRange(0, slist.Count);
            //msg.Append("0: ");
            String[] choices = (((TextBox)sender).Text).Split('\n');
            //msg.Append(choices.Count().ToString()).AppendLine();
            foreach (String s in choices)
            {
               if (s.Trim() != "")
               {
                    //msg.Append(s).Append(", ");
                    slist.Add(s.Trim());
               }
                
            }
            //MessageBox.Show(msg.ToString());
        }

        private void SiteColumnFormType_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {            
            GridLengthConverter glc = new GridLengthConverter();
            
            SiteColAdditionalInfoRow.Height = (GridLength)glc.ConvertFromString("1");
            SiteColumnFormDesc.Height = 120;
            SiteColAdditionalInfoRowLabelStackPanel.Children.RemoveRange(0, SiteColAdditionalInfoRowLabelStackPanel.Children.Count);
            SiteColAdditionalInfoStackPanel.Children.RemoveRange(0, SiteColAdditionalInfoStackPanel.Children.Count);
            //the field is now in it's "default" state.

            Thickness margin = new Thickness(0, 4, 5, 3); // margin for the gui elements in the additional info stack panel


            if (((ComboBoxItem)((ComboBox)e.Source).SelectedItem) != null)
            {
                SiteColumn sc = SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn());
                sc.Type = ((SiteColumnType)((ComboBoxItem)((ComboBox)e.Source).SelectedItem).Tag);
                if (((SiteColumnType)((ComboBoxItem)((ComboBox)e.Source).SelectedItem).Tag) == SiteColumnType.SINGLE_LINE_OF_TEXT)
                {
                    if (!sc.additionalAttributes.ContainsKey(SiteColumnType.SINGLE_LINE_OF_TEXT))
                    {
                        sc.additionalAttributes.Add(SiteColumnType.SINGLE_LINE_OF_TEXT, new Dictionary<string, string>());
                    }

                    if (!sc.additionalAttributes[SiteColumnType.SINGLE_LINE_OF_TEXT].ContainsKey("MaxLength"))
                    {
                        sc.additionalAttributes[SiteColumnType.SINGLE_LINE_OF_TEXT].Add("MaxLength", "255");
                    }

                    Label lab = new Label();
                    lab.Content = "Max Length (characters): ";
                    SiteColAdditionalInfoRowLabelStackPanel.Children.Add(lab);

                    TextBox tb = new TextBox();
                    tb.Name = "maxLengthTextBox";
                    tb.Margin = new Thickness(0, 0, 5, 0);
                    tb.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
                    tb.IsEnabled = true;
                    tb.Tag = SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn());
                    tb.FontWeight = FontWeights.Normal;
                    tb.Text = sc.additionalAttributes[SiteColumnType.SINGLE_LINE_OF_TEXT]["MaxLength"];
                    tb.TextChanged += new TextChangedEventHandler((object o, TextChangedEventArgs a) =>
                    {
                        try
                        {
                            int check = Int32.Parse(tb.Text);
                            sc.additionalAttributes[SiteColumnType.SINGLE_LINE_OF_TEXT]["MaxLength"] = check.ToString();
                        }
                        catch
                        {
                            tb.Text = sc.additionalAttributes[SiteColumnType.SINGLE_LINE_OF_TEXT]["MaxLength"];
                        }
                    });
                    SiteColAdditionalInfoStackPanel.Children.Add(tb);


                    SiteColumnFormDesc.Height = 60;
                    SiteColAdditionalInfoRow.Height = (GridLength)glc.ConvertFromString("25");
                }
                else if ((SiteColumnType)((ComboBoxItem)((ComboBox)e.Source).SelectedItem).Tag == SiteColumnType.MULTIPLES_LINES_OF_TEXT)
                {
                    if (!sc.additionalAttributes.ContainsKey(SiteColumnType.MULTIPLES_LINES_OF_TEXT))
                    {
                        sc.additionalAttributes.Add(SiteColumnType.MULTIPLES_LINES_OF_TEXT, new Dictionary<string, string>());
                    }

                    if (!sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT].ContainsKey("NumLines"))
                    {
                        sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT].Add("NumLines", "10");
                    }
                    if (!sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT].ContainsKey("RichText"))
                    {
                        sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT].Add("RichText", "False");
                    }
                    if (!sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT].ContainsKey("RichTextMode"))
                    {
                        sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT].Add("RichTextMode", "FullHtml");
                    }

                    foreach (String s in new String[] { "Max Lines", "Format" })
                    {
                        Label lab = new Label();
                        lab.Content = s;
                        SiteColAdditionalInfoRowLabelStackPanel.Children.Add(lab);
                    }

                    TextBox tb = new TextBox();
                    tb.Name = "linesTextBox";
                    tb.Margin = new Thickness(0, 0, 5, 0);
                    tb.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
                    tb.IsEnabled = true;
                    tb.Tag = SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn());
                    tb.FontWeight = FontWeights.Normal;
                    tb.Text = sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT]["NumLines"];
                    tb.TextChanged += new TextChangedEventHandler((object o, TextChangedEventArgs a) =>
                    {
                        try
                        {
                            int check = Int32.Parse(tb.Text);
                            sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT]["NumLines"] = check.ToString();
                        }
                        catch
                        {
                            tb.Text = sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT]["NumLines"];
                        }
                    });
                    SiteColAdditionalInfoStackPanel.Children.Add(tb);

                    StackPanel formatSP = new StackPanel();
                    formatSP.Orientation = Orientation.Horizontal;
                    RadioButton plainRadio = new RadioButton();
                    plainRadio.IsChecked = sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT]["RichText"] != "True";
                    plainRadio.Checked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT]["RichText"] = "False"; sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT]["RichTextMode"] = "Compatible"; });
                    plainRadio.GroupName = "format2Radios";
                    plainRadio.Content = "Plain Text";
                    plainRadio.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                    formatSP.Children.Add(plainRadio);

                    RadioButton richRadio = new RadioButton();
                    richRadio.IsChecked = sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT]["RichText"] == "True" && sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT]["RichTextMode"] == "Compatible";
                    richRadio.Checked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT]["RichText"] = "True"; sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT]["RichTextMode"] = "Compatible"; });
                    richRadio.Margin = new Thickness(10, 0, 0, 0);
                    richRadio.GroupName = "format2Radios";
                    richRadio.Content = "Rich Text";
                    richRadio.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                    formatSP.Children.Add(richRadio);

                    RadioButton fullRadio = new RadioButton();
                    fullRadio.IsChecked = sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT]["RichText"] == "True" && sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT]["RichTextMode"] == "FullHtml";
                    fullRadio.Checked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT]["RichText"] = "True"; sc.additionalAttributes[SiteColumnType.MULTIPLES_LINES_OF_TEXT]["RichTextMode"] = "FullHtml"; });
                    fullRadio.Margin = new Thickness(10, 0, 0, 0);
                    fullRadio.GroupName = "format2Radios";
                    fullRadio.Content = "Enhanced Rich Text";
                    fullRadio.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                    formatSP.Children.Add(fullRadio);

                    formatSP.Margin = margin;
                    SiteColAdditionalInfoStackPanel.Children.Add(formatSP);

                    SiteColumnFormDesc.Height = 30;
                    SiteColAdditionalInfoRow.Height = (GridLength)glc.ConvertFromString("45");
                }
                else if (((SiteColumnType)((ComboBoxItem)((ComboBox)e.Source).SelectedItem).Tag) == SiteColumnType.CHOICE)
                {
                    if (!sc.additionalAttributes.ContainsKey(SiteColumnType.CHOICE))
                    {
                        sc.additionalAttributes.Add(SiteColumnType.CHOICE, new Dictionary<string, string>());
                    }

                    if (!sc.additionalAttributes[SiteColumnType.CHOICE].ContainsKey("FillIn"))
                    {
                        sc.additionalAttributes[SiteColumnType.CHOICE].Add("FillIn", "False");
                    }
                    if (!sc.additionalAttributes[SiteColumnType.CHOICE].ContainsKey("Format"))
                    {
                        sc.additionalAttributes[SiteColumnType.CHOICE].Add("Format", "Dropdown");
                        // enum: Dropdown, or RadioButtons
                    }

                    foreach (String s in new String[] { "Allow Fill-In", "Format", "Available Choices:\n(Seperate each\nchoice with a\nnew line)" })
                    {
                        Label lab = new Label();
                        lab.Content = s;
                        SiteColAdditionalInfoRowLabelStackPanel.Children.Add(lab);
                    }

                    CheckBox fillInBox = new CheckBox();
                    fillInBox.Margin = margin;
                    fillInBox.IsChecked = sc.additionalAttributes[SiteColumnType.CHOICE]["FillIn"] == "True";
                    fillInBox.Checked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.CHOICE]["FillIn"] = "True"; });
                    fillInBox.Unchecked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.CHOICE]["FillIn"] = "False"; });
                    SiteColAdditionalInfoStackPanel.Children.Add(fillInBox);

                    StackPanel radioSP = new StackPanel();
                    radioSP.Orientation = Orientation.Horizontal;
                    RadioButton radioRadio = new RadioButton();
                    radioRadio.IsChecked = sc.additionalAttributes[SiteColumnType.CHOICE]["Format"] == "RadioButtons";
                    radioRadio.Checked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.CHOICE]["Format"] = "RadioButtons"; });
                    radioRadio.GroupName = "formatRadios";
                    radioRadio.Content = "Radio Buttons";
                    radioRadio.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                    radioSP.Children.Add(radioRadio);
                    RadioButton dropdownRadio = new RadioButton();
                    dropdownRadio.IsChecked = sc.additionalAttributes[SiteColumnType.CHOICE]["Format"] == "Dropdown";
                    dropdownRadio.Checked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.CHOICE]["Format"] = "Dropdown"; });
                    dropdownRadio.Margin = new Thickness(10, 0, 0, 0);
                    dropdownRadio.GroupName = "formatRadios";
                    dropdownRadio.Content = "Dropdown";
                    dropdownRadio.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                    radioSP.Children.Add(dropdownRadio);
                    radioSP.Margin = margin;
                    SiteColAdditionalInfoStackPanel.Children.Add(radioSP);

                    TextBox tb = new TextBox();
                    tb.Tag = SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn()).SList;
                    tb.Margin = margin;
                    tb.MaxHeight = 70;
                    tb.Height = 70;
                    tb.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
                    tb.IsEnabled = true;
                    tb.AcceptsReturn = true;
                    tb.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
                    tb.FontWeight = FontWeights.Normal;
                    StringBuilder tbContent = new StringBuilder("");
                    foreach (String s in (List<String>)tb.Tag)
                    {
                        tbContent.Append(s).AppendLine();
                    }
                    tb.Text = tbContent.ToString();
                    tb.TextChanged += new TextChangedEventHandler(choiceTextBox_TextInput);

                    SiteColAdditionalInfoStackPanel.Children.Add(tb);


                    SiteColumnFormDesc.Height = 50;
                    SiteColAdditionalInfoRow.Height = (GridLength)glc.ConvertFromString("150");
                }
                else if (((SiteColumnType)((ComboBoxItem)((ComboBox)e.Source).SelectedItem).Tag) == SiteColumnType.TASK_OUTCOME)
                {
                    if (!sc.additionalAttributes.ContainsKey(SiteColumnType.TASK_OUTCOME))
                    {
                        sc.additionalAttributes.Add(SiteColumnType.TASK_OUTCOME, new Dictionary<string, string>());
                    }

                    Label lab = new Label();
                    lab.Content = "Available Choices:\n(Seperate each\nchoice with a\nnew line)";
                    SiteColAdditionalInfoRowLabelStackPanel.Children.Add(lab);

                    TextBox tb = new TextBox();
                    tb.Name = "choicesTextBox";
                    tb.Tag = SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn()).SList;
                    tb.Margin = margin;
                    tb.MaxHeight = 70;
                    tb.Height = 70;
                    tb.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
                    tb.IsEnabled = true;
                    tb.AcceptsReturn = true;
                    tb.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
                    tb.FontWeight = FontWeights.Normal;
                    StringBuilder tbContent = new StringBuilder("");
                    foreach (String s in (List<String>)tb.Tag)
                    {
                        tbContent.Append(s).AppendLine();
                    }
                    tb.Text = tbContent.ToString();
                    tb.TextChanged += new TextChangedEventHandler(choiceTextBox_TextInput);

                    SiteColAdditionalInfoStackPanel.Children.Add(tb);


                    SiteColumnFormDesc.Height = 70;
                    SiteColAdditionalInfoRow.Height = (GridLength)glc.ConvertFromString("80");
                }
                else if (((SiteColumnType)((ComboBoxItem)((ComboBox)e.Source).SelectedItem).Tag) == SiteColumnType.MULTICHOICE)
                {
                    if (!sc.additionalAttributes.ContainsKey(SiteColumnType.MULTICHOICE))
                    {
                        sc.additionalAttributes.Add(SiteColumnType.MULTICHOICE, new Dictionary<string, string>());
                    }

                    if (!sc.additionalAttributes[SiteColumnType.MULTICHOICE].ContainsKey("FillIn"))
                    {
                        sc.additionalAttributes[SiteColumnType.MULTICHOICE].Add("FillIn", "False");
                    }

                    foreach (String s in new String[] { "Allow Fill-In", "Available Choices:\n(Seperate each\nchoice with a\nnew line)" })
                    {
                        Label lab = new Label();
                        lab.Content = s;
                        SiteColAdditionalInfoRowLabelStackPanel.Children.Add(lab);
                    }

                    CheckBox fillInBox = new CheckBox();
                    fillInBox.Margin = margin;
                    fillInBox.IsChecked = sc.additionalAttributes[SiteColumnType.MULTICHOICE]["FillIn"] == "True";
                    fillInBox.Checked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.MULTICHOICE]["FillIn"] = "True"; });
                    fillInBox.Unchecked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.MULTICHOICE]["FillIn"] = "False"; });
                    SiteColAdditionalInfoStackPanel.Children.Add(fillInBox);

                    TextBox tb = new TextBox();
                    tb.Name = "multiChoicesTextBox";
                    tb.Tag = SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn()).SList;
                    tb.Margin = margin;
                    tb.MaxHeight = 70;
                    tb.Height = 70;
                    tb.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
                    tb.IsEnabled = true;
                    tb.AcceptsReturn = true;
                    tb.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
                    tb.FontWeight = FontWeights.Normal;
                    StringBuilder tbContent = new StringBuilder("");
                    foreach (String s in (List<String>)tb.Tag)
                    {
                        tbContent.Append(s).AppendLine();
                    }
                    tb.Text = tbContent.ToString();
                    tb.TextChanged += new TextChangedEventHandler(choiceTextBox_TextInput);

                    SiteColAdditionalInfoStackPanel.Children.Add(tb);


                    SiteColumnFormDesc.Height = 60;
                    SiteColAdditionalInfoRow.Height = (GridLength)glc.ConvertFromString("120");
                }
                else if (((SiteColumnType)((ComboBoxItem)((ComboBox)e.Source).SelectedItem).Tag) == SiteColumnType.NUMBER)
                {
                    if (!sc.additionalAttributes.ContainsKey(SiteColumnType.NUMBER))
                    {
                        sc.additionalAttributes.Add(SiteColumnType.NUMBER, new Dictionary<string, string>());
                    }

                    if (!sc.additionalAttributes[SiteColumnType.NUMBER].ContainsKey("ShowAsPercentage"))
                    {
                        sc.additionalAttributes[SiteColumnType.NUMBER].Add("ShowAsPercentage", "False");
                    }
                    if (!sc.additionalAttributes[SiteColumnType.NUMBER].ContainsKey("Min"))
                    {
                        sc.additionalAttributes[SiteColumnType.NUMBER].Add("Min", "");
                    }
                    if (!sc.additionalAttributes[SiteColumnType.NUMBER].ContainsKey("Max"))
                    {
                        sc.additionalAttributes[SiteColumnType.NUMBER].Add("Max", "");
                    }

                    foreach (String s in new String[] { "Show As Percentage", "Minimum", "Maximum" })
                    {
                        Label lab = new Label();
                        lab.Content = s;
                        SiteColAdditionalInfoRowLabelStackPanel.Children.Add(lab);
                    }

                    CheckBox percentageBox = new CheckBox();
                    percentageBox.Margin = margin;
                    percentageBox.IsChecked = sc.additionalAttributes[SiteColumnType.NUMBER]["ShowAsPercentage"] == "True";
                    percentageBox.Checked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.NUMBER]["ShowAsPercentage"] = "True"; });
                    percentageBox.Unchecked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.NUMBER]["ShowAsPercentage"] = "False"; });
                    SiteColAdditionalInfoStackPanel.Children.Add(percentageBox);

                    TextBox tb1 = new TextBox();
                    tb1.Margin = margin;
                    tb1.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
                    tb1.FontWeight = FontWeights.Normal;
                    tb1.Text = sc.additionalAttributes[SiteColumnType.NUMBER]["Min"];
                    tb1.TextChanged += new TextChangedEventHandler((object o, TextChangedEventArgs a) =>
                    {
                        try
                        {
                            Double check = Double.Parse(tb1.Text);
                            sc.additionalAttributes[SiteColumnType.NUMBER]["Min"] = check.ToString();
                        }
                        catch
                        {
                            tb1.Text = sc.additionalAttributes[SiteColumnType.NUMBER]["Min"];
                        }
                    });
                    SiteColAdditionalInfoStackPanel.Children.Add(tb1);

                    TextBox tb2 = new TextBox();
                    tb2.Margin = margin;
                    tb2.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
                    tb2.FontWeight = FontWeights.Normal;
                    tb2.Text = sc.additionalAttributes[SiteColumnType.NUMBER]["Max"];
                    tb2.TextChanged += new TextChangedEventHandler((object o, TextChangedEventArgs a) =>
                    {
                        try
                        {
                            Double check = Double.Parse(tb2.Text);
                            sc.additionalAttributes[SiteColumnType.NUMBER]["Max"] = check.ToString();
                        }
                        catch
                        {
                            tb1.Text = sc.additionalAttributes[SiteColumnType.NUMBER]["Max"];
                        }
                    });
                    SiteColAdditionalInfoStackPanel.Children.Add(tb2);

                    SiteColumnFormDesc.Height = 75;
                    SiteColAdditionalInfoRow.Height = (GridLength)glc.ConvertFromString("75");

                }
                else if (((SiteColumnType)((ComboBoxItem)((ComboBox)e.Source).SelectedItem).Tag) == SiteColumnType.CURRENCY)
                {
                    if (!sc.additionalAttributes.ContainsKey(SiteColumnType.CURRENCY))
                    {
                        sc.additionalAttributes.Add(SiteColumnType.CURRENCY, new Dictionary<string, string>());
                    }

                    if (!sc.additionalAttributes[SiteColumnType.CURRENCY].ContainsKey("CurrencyLCID"))
                    {
                        sc.additionalAttributes[SiteColumnType.CURRENCY].Add("CurrencyLCID", "1033");
                    }
                    if (!sc.additionalAttributes[SiteColumnType.CURRENCY].ContainsKey("Min"))
                    {
                        sc.additionalAttributes[SiteColumnType.CURRENCY].Add("Min", "");
                    }
                    if (!sc.additionalAttributes[SiteColumnType.CURRENCY].ContainsKey("Max"))
                    {
                        sc.additionalAttributes[SiteColumnType.CURRENCY].Add("Max", "");
                    }

                    foreach (String s in new String[] { "Minimum", "Maximum" })
                    {
                        Label lab = new Label();
                        lab.Content = s;
                        SiteColAdditionalInfoRowLabelStackPanel.Children.Add(lab);
                    }



                    TextBox tb1 = new TextBox();
                    tb1.Margin = margin;
                    tb1.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
                    tb1.FontWeight = FontWeights.Normal;
                    tb1.Text = sc.additionalAttributes[SiteColumnType.CURRENCY]["Min"];
                    tb1.TextChanged += new TextChangedEventHandler((object o, TextChangedEventArgs a) =>
                    {
                        try
                        {
                            Double check = Double.Parse(tb1.Text);
                            sc.additionalAttributes[SiteColumnType.CURRENCY]["Min"] = check.ToString();
                        }
                        catch
                        {
                            tb1.Text = sc.additionalAttributes[SiteColumnType.CURRENCY]["Min"];
                        }
                    });
                    SiteColAdditionalInfoStackPanel.Children.Add(tb1);

                    TextBox tb2 = new TextBox();
                    tb2.Margin = margin;
                    tb2.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
                    tb2.FontWeight = FontWeights.Normal;
                    tb2.Text = sc.additionalAttributes[SiteColumnType.CURRENCY]["Max"];
                    tb2.TextChanged += new TextChangedEventHandler((object o, TextChangedEventArgs a) =>
                    {
                        try
                        {
                            Double check = Double.Parse(tb2.Text);
                            sc.additionalAttributes[SiteColumnType.CURRENCY]["Max"] = check.ToString();
                        }
                        catch
                        {
                            tb1.Text = sc.additionalAttributes[SiteColumnType.CURRENCY]["Max"];
                        }
                    });
                    SiteColAdditionalInfoStackPanel.Children.Add(tb2);

                    SiteColumnFormDesc.Height = 70;
                    SiteColAdditionalInfoRow.Height = (GridLength)glc.ConvertFromString("60");
                }
                else if (((SiteColumnType)((ComboBoxItem)((ComboBox)e.Source).SelectedItem).Tag) == SiteColumnType.DATE_AND_TIME)
                {
                    if (!sc.additionalAttributes.ContainsKey(SiteColumnType.DATE_AND_TIME))
                    {
                        sc.additionalAttributes.Add(SiteColumnType.DATE_AND_TIME, new Dictionary<string, string>());
                    }

                    if (!sc.additionalAttributes[SiteColumnType.DATE_AND_TIME].ContainsKey("FriendlyDisplay"))
                    {
                        sc.additionalAttributes[SiteColumnType.DATE_AND_TIME].Add("FriendlyDisplay", "Disabled");
                        // enum: Disabled, or Relative
                    }
                    if (!sc.additionalAttributes[SiteColumnType.DATE_AND_TIME].ContainsKey("DisplayFormat"))
                    {
                        sc.additionalAttributes[SiteColumnType.DATE_AND_TIME].Add("DisplayFormat", "DateTime");
                        // enum: DateTime, or DateOnly
                    }
                    foreach (String s in new String[] { "Friendly Display", "Display Format" })
                    {
                        Label lab = new Label();
                        lab.Content = s;
                        SiteColAdditionalInfoRowLabelStackPanel.Children.Add(lab);
                    }

                    CheckBox friendlyBox = new CheckBox();
                    friendlyBox.Margin = margin;
                    friendlyBox.IsChecked = sc.additionalAttributes[SiteColumnType.DATE_AND_TIME]["FriendlyDisplay"] == "Relative";
                    friendlyBox.Checked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.DATE_AND_TIME]["FriendlyDisplay"] = "Relative"; });
                    friendlyBox.Unchecked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.DATE_AND_TIME]["FriendlyDisplay"] = "Disabled"; });
                    SiteColAdditionalInfoStackPanel.Children.Add(friendlyBox);

                    StackPanel radioSP = new StackPanel();
                    radioSP.Orientation = Orientation.Horizontal;
                    RadioButton datetimeRadio = new RadioButton();
                    datetimeRadio.IsChecked = sc.additionalAttributes[SiteColumnType.DATE_AND_TIME]["DisplayFormat"] == "DateTime";
                    datetimeRadio.Checked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.DATE_AND_TIME]["DisplayFormat"] = "DateTime"; });
                    datetimeRadio.GroupName = "format3Radios";
                    datetimeRadio.Content = "Date & Time";
                    datetimeRadio.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                    radioSP.Children.Add(datetimeRadio);
                    RadioButton dateonlyRadio = new RadioButton();
                    dateonlyRadio.IsChecked = sc.additionalAttributes[SiteColumnType.DATE_AND_TIME]["DisplayFormat"] == "DateOnly";
                    dateonlyRadio.Checked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.DATE_AND_TIME]["DisplayFormat"] = "DateOnly"; });
                    dateonlyRadio.Margin = new Thickness(10, 0, 0, 0);
                    dateonlyRadio.GroupName = "format3Radios";
                    dateonlyRadio.Content = "Date Only";
                    dateonlyRadio.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                    radioSP.Children.Add(dateonlyRadio);;
                    radioSP.Margin = margin;
                    SiteColAdditionalInfoStackPanel.Children.Add(radioSP);

                    SiteColumnFormDesc.Height = 70;
                    SiteColAdditionalInfoRow.Height = (GridLength)glc.ConvertFromString("60");
                }
                else if (((SiteColumnType)((ComboBoxItem)((ComboBox)e.Source).SelectedItem).Tag) == SiteColumnType.PERSON_OR_GROUP)
                {
                    if (!sc.additionalAttributes.ContainsKey(SiteColumnType.PERSON_OR_GROUP))
                    {
                        sc.additionalAttributes.Add(SiteColumnType.PERSON_OR_GROUP, new Dictionary<string, string>());
                    }

                    if (!sc.additionalAttributes[SiteColumnType.PERSON_OR_GROUP].ContainsKey("AllowMultipleValues"))
                    {
                        sc.additionalAttributes[SiteColumnType.PERSON_OR_GROUP].Add("AllowMultipleValues", "False");
                    }
                    if (!sc.additionalAttributes[SiteColumnType.PERSON_OR_GROUP].ContainsKey("SelectionMode"))
                    {
                        sc.additionalAttributes[SiteColumnType.PERSON_OR_GROUP].Add("SelectionMode", "PeopleAndGroups");
                        // enum: PeopleAndGroups, or PeopleOnly
                    }
                    foreach (String s in new String[] { "Allow Multiple", "Selection Mode" })
                    {
                        Label lab = new Label();
                        lab.Content = s;
                        SiteColAdditionalInfoRowLabelStackPanel.Children.Add(lab);
                    }

                    CheckBox multipleBox = new CheckBox();
                    multipleBox.Margin = margin;
                    multipleBox.IsChecked = sc.additionalAttributes[SiteColumnType.PERSON_OR_GROUP]["AllowMultipleValues"] == "True";
                    multipleBox.Checked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.PERSON_OR_GROUP]["AllowMultipleValues"] = "True"; });
                    multipleBox.Unchecked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.PERSON_OR_GROUP]["AllowMultipleValues"] = "False"; });
                    SiteColAdditionalInfoStackPanel.Children.Add(multipleBox);

                    StackPanel radioSP = new StackPanel();
                    radioSP.Orientation = Orientation.Horizontal;
                    RadioButton peoplegroupsRadio = new RadioButton();
                    peoplegroupsRadio.IsChecked = sc.additionalAttributes[SiteColumnType.PERSON_OR_GROUP]["SelectionMode"] == "PeopleAndGroups";
                    peoplegroupsRadio.Checked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.PERSON_OR_GROUP]["SelectionMode"] = "PeopleAndGroups"; });
                    peoplegroupsRadio.GroupName = "format4Radios";
                    peoplegroupsRadio.Content = "People & Groups";
                    peoplegroupsRadio.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                    radioSP.Children.Add(peoplegroupsRadio);
                    RadioButton peopleonlyRadio = new RadioButton();
                    peopleonlyRadio.IsChecked = sc.additionalAttributes[SiteColumnType.PERSON_OR_GROUP]["SelectionMode"] == "PeopleOnly";
                    peopleonlyRadio.Checked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.PERSON_OR_GROUP]["SelectionMode"] = "PeopleOnly"; });
                    peopleonlyRadio.Margin = new Thickness(10, 0, 0, 0);
                    peopleonlyRadio.GroupName = "format4Radios";
                    peopleonlyRadio.Content = "People Only";
                    peopleonlyRadio.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                    radioSP.Children.Add(peopleonlyRadio);
                    radioSP.Margin = margin;
                    SiteColAdditionalInfoStackPanel.Children.Add(radioSP);

                    SiteColumnFormDesc.Height = 70;
                    SiteColAdditionalInfoRow.Height = (GridLength)glc.ConvertFromString("60");
                }
                else if (((SiteColumnType)((ComboBoxItem)((ComboBox)e.Source).SelectedItem).Tag) == SiteColumnType.HYPERLINK_OR_PICTURE)
                {
                    if (!sc.additionalAttributes.ContainsKey(SiteColumnType.HYPERLINK_OR_PICTURE))
                    {
                        sc.additionalAttributes.Add(SiteColumnType.HYPERLINK_OR_PICTURE, new Dictionary<string, string>());
                    }

                    if (!sc.additionalAttributes[SiteColumnType.HYPERLINK_OR_PICTURE].ContainsKey("FormatType"))
                    {
                        sc.additionalAttributes[SiteColumnType.HYPERLINK_OR_PICTURE].Add("FormatType", "Hyperlink");
                        // enum: Hyperlink, or Image
                    }

                    foreach (String s in new String[] { "Format" })
                    {
                        Label lab = new Label();
                        lab.Content = s;
                        SiteColAdditionalInfoRowLabelStackPanel.Children.Add(lab);
                    }

                    StackPanel radioSP = new StackPanel();
                    radioSP.Orientation = Orientation.Horizontal;
                    RadioButton hyperlinkRadio = new RadioButton();
                    hyperlinkRadio.IsChecked = sc.additionalAttributes[SiteColumnType.HYPERLINK_OR_PICTURE]["FormatType"] == "Hyperlink";
                    hyperlinkRadio.Checked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.HYPERLINK_OR_PICTURE]["FormatType"] = "Hyperlink"; });
                    hyperlinkRadio.GroupName = "format5Radios";
                    hyperlinkRadio.Content = "Hyperlink";
                    hyperlinkRadio.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                    radioSP.Children.Add(hyperlinkRadio);
                    RadioButton imageRadio = new RadioButton();
                    imageRadio.IsChecked = sc.additionalAttributes[SiteColumnType.HYPERLINK_OR_PICTURE]["FormatType"] == "Image";
                    imageRadio.Checked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.HYPERLINK_OR_PICTURE]["FormatType"] = "Image"; });
                    imageRadio.Margin = new Thickness(10, 0, 0, 0);
                    imageRadio.GroupName = "format5Radios";
                    imageRadio.Content = "Image";
                    imageRadio.VerticalAlignment = System.Windows.VerticalAlignment.Center;
                    radioSP.Children.Add(imageRadio);
                    radioSP.Margin = margin;
                    SiteColAdditionalInfoStackPanel.Children.Add(radioSP);

                    SiteColumnFormDesc.Height = 80;
                    SiteColAdditionalInfoRow.Height = (GridLength)glc.ConvertFromString("35");

                }
                else if (((SiteColumnType)((ComboBoxItem)((ComboBox)e.Source).SelectedItem).Tag) == SiteColumnType.CALCULATED)
                {
                    if (!sc.additionalAttributes.ContainsKey(SiteColumnType.CALCULATED))
                    {
                        sc.additionalAttributes.Add(SiteColumnType.CALCULATED, new Dictionary<string, string>());
                    }

                    if (!sc.additionalAttributes[SiteColumnType.CALCULATED].ContainsKey("Formula"))
                    {
                        sc.additionalAttributes[SiteColumnType.CALCULATED].Add("Formula", "");
                    }

                    Label lab = new Label();
                    lab.Content = "Formula: ";
                    SiteColAdditionalInfoRowLabelStackPanel.Children.Add(lab);

                    TextBox tb = new TextBox();
                    tb.Name = "formulaTextBox";
                    tb.Margin = new Thickness(0, 0, 5, 0);
                    tb.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
                    tb.IsEnabled = true;
                    tb.Tag = SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn());
                    tb.FontWeight = FontWeights.Normal;
                    tb.Text = sc.additionalAttributes[SiteColumnType.CALCULATED]["Formula"];
                    tb.TextChanged += new TextChangedEventHandler((object o, TextChangedEventArgs a) =>
                    {
                        sc.additionalAttributes[SiteColumnType.CALCULATED]["Formula"] = tb.Text;
                    });
                    SiteColAdditionalInfoStackPanel.Children.Add(tb);

                    SiteColumnFormDesc.Height = 60;
                    SiteColAdditionalInfoRow.Height = (GridLength)glc.ConvertFromString("25");

                }
                else if (((SiteColumnType)((ComboBoxItem)((ComboBox)e.Source).SelectedItem).Tag) == SiteColumnType.FULL_HTML_WITH_FORMATTING)
                {
                    if (!sc.additionalAttributes.ContainsKey(SiteColumnType.FULL_HTML_WITH_FORMATTING))
                    {
                        sc.additionalAttributes.Add(SiteColumnType.FULL_HTML_WITH_FORMATTING, new Dictionary<string, string>());
                    }
                }
                else if (((SiteColumnType)((ComboBoxItem)((ComboBox)e.Source).SelectedItem).Tag) == SiteColumnType.IMAGE_WITH_FORMATTING)
                {
                    if (!sc.additionalAttributes.ContainsKey(SiteColumnType.FULL_HTML_WITH_FORMATTING))
                    {
                        sc.additionalAttributes.Add(SiteColumnType.FULL_HTML_WITH_FORMATTING, new Dictionary<string, string>());
                    }
                }
                else if (((SiteColumnType)((ComboBoxItem)((ComboBox)e.Source).SelectedItem).Tag) == SiteColumnType.HYPERLINK_WITH_FORMATTING)
                {
                    if (!sc.additionalAttributes.ContainsKey(SiteColumnType.FULL_HTML_WITH_FORMATTING))
                    {
                        sc.additionalAttributes.Add(SiteColumnType.FULL_HTML_WITH_FORMATTING, new Dictionary<string, string>());
                    }
                }
                else if (((SiteColumnType)((ComboBoxItem)((ComboBox)e.Source).SelectedItem).Tag) == SiteColumnType.SUMMARY_LINKS_DATA)
                {
                    if (!sc.additionalAttributes.ContainsKey(SiteColumnType.FULL_HTML_WITH_FORMATTING))
                    {
                        sc.additionalAttributes.Add(SiteColumnType.FULL_HTML_WITH_FORMATTING, new Dictionary<string, string>());
                    }
                }
                else if (((SiteColumnType)((ComboBoxItem)((ComboBox)e.Source).SelectedItem).Tag) == SiteColumnType.RICH_MEDIA_DATA)
                {
                    if (!sc.additionalAttributes.ContainsKey(SiteColumnType.FULL_HTML_WITH_FORMATTING))
                    {
                        sc.additionalAttributes.Add(SiteColumnType.FULL_HTML_WITH_FORMATTING, new Dictionary<string, string>());
                    }
                }
                else if (((SiteColumnType)((ComboBoxItem)((ComboBox)e.Source).SelectedItem).Tag) == SiteColumnType.MANAGED_METADATA)
                {
                    if (!sc.additionalAttributes.ContainsKey(SiteColumnType.MANAGED_METADATA))
                    {
                        sc.additionalAttributes.Add(SiteColumnType.MANAGED_METADATA, new Dictionary<string, string>());
                    }
                    if (!sc.additionalAttributes[SiteColumnType.MANAGED_METADATA].ContainsKey("AllowMultipleValues"))
                    {
                        sc.additionalAttributes[SiteColumnType.MANAGED_METADATA].Add("AllowMultipleValues", "False");
                    }

                    //MessageBox.Show("It's a metadata field!!");
                    foreach (String s in new String[] { "Allow Multiple Values", "Taggables Terms" })
                    {
                        Label lab = new Label();
                        lab.Content = s;
                        SiteColAdditionalInfoRowLabelStackPanel.Children.Add(lab);
                    }

                    CheckBox percentageBox = new CheckBox();
                    percentageBox.Margin = margin;
                    percentageBox.IsChecked = sc.additionalAttributes[SiteColumnType.MANAGED_METADATA]["AllowMultipleValues"] == "True";
                    percentageBox.Checked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.MANAGED_METADATA]["AllowMultipleValues"] = "True"; });
                    percentageBox.Unchecked += new RoutedEventHandler((object o, RoutedEventArgs a) => { sc.additionalAttributes[SiteColumnType.MANAGED_METADATA]["AllowMultipleValues"] = "False"; });
                    SiteColAdditionalInfoStackPanel.Children.Add(percentageBox);

                    DockPanel SiteColAdditionalInfoDockPanel = new DockPanel();
                    TextBox tb = new TextBox();
                    tb.Name = "termNameTextBox";
                    tb.Tag = SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn()).Tag;
                    tb.Margin = new Thickness(0, 0, 5, 0);
                    tb.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
                    tb.IsEnabled = false;
                    try
                    {
                        tb.Text = ((Term)tb.Tag).Name;
                    }
                    catch (Exception ex)
                    {
                        tb.Text = "";
                        Log.Append("SiteColumnFormType_SelectionChanged Exception:").Append(ex.Message).AppendLine().AppendLine("This above exception was probably due to the Tag element not being initialized yet.");
                    }

                    Button nbtn = new Button();
                    nbtn.Padding = new Thickness(0);
                    StackPanel nbtnSP = new StackPanel();
                    nbtnSP.Orientation = Orientation.Horizontal;
                    Image nbtnIcon = new Image();
                    nbtnIcon.Source = (ImageSource)((Image)FindResource("tagIcon")).Source;
                    nbtnIcon.Width = 13;
                    nbtnIcon.Height = 13;
                    Label nbtnLabel = new Label();
                    nbtnLabel.Content = "Manage Tags";
                    nbtnSP.Children.Add(nbtnIcon);
                    nbtnSP.Children.Add(nbtnLabel);
                    nbtn.Content = nbtnSP;
                    nbtn.Command = CustomCommands.Commands.ManageSiteColumnMetadataTagsCommand;
                    nbtn.CommandParameter = tb;
                    nbtn.Margin = new Thickness(5, 5, 5, 5);

                    Button vbtn = new Button();
                    vbtn.Content = "Popup List";
                    vbtn.HorizontalAlignment = HorizontalAlignment.Right;
                    vbtn.Margin = new Thickness(5, 5, 5, 5);
                    vbtn.Command = CustomCommands.Commands.PopupSiteColumnMetadataTagsCommand;
                    vbtn.CommandParameter = tb;


                    SiteColAdditionalInfoDockPanel.Children.Add(nbtn);
                    SiteColAdditionalInfoDockPanel.Children.Add(vbtn);
                    DockPanel.SetDock(vbtn, Dock.Right);
                    SiteColAdditionalInfoDockPanel.Children.Add(tb);

                    SiteColAdditionalInfoStackPanel.Children.Add(SiteColAdditionalInfoDockPanel);

                    SiteColumnFormDesc.Height = 60;
                    SiteColAdditionalInfoRow.Height = (GridLength)glc.ConvertFromString("70");
                }
            }
            else
            {
                // selection was null
            }
        }

        private void SiteColumnsTab_GotFocus(object sender, RoutedEventArgs e)
        {
            UpdateSiteColumnAdditionalInfoMetadataTextBox();
        }

        private void SiteColChangedEvent(object sender, RoutedEventArgs e)
        {
            if (!changingSiteColumns)
            {
                bool b;
                try
                {
                    b = SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn()).Name != SiteColumnFormName.Text;
                }
                catch
                {
                    b = true;
                }
                SiteColsSave(SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn()));
                if (b) { UpdateSiteColumnList(); }
            }
        }

        private void ContentTypeList_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            changingContentTypes = true;
            UpdateContentTypeFields(SaveFile.contentTypes.GetContentTypeByName(GetSelectedContentType()));
            changingContentTypes = false;
        }

        private void AddSiteColumnGroupButton_Click(object sender, RoutedEventArgs e)
        {
            String newName = Prompt.Show("Enter the new group name.", "New Site Column Group");
            if (newName == null || newName.Length <= 0)
            {

            }
            else if (!SiteColumn.SiteColumnGroups.Contains(newName))
            {
                SiteColumn.SiteColumnGroups.Add(newName);
                SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn()).PutInto = newName;
                InitializeSiteColumnGroupDropdown(newName);
                UpdateSiteColumnFields(SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn()));
            }
            else
            {
                MessageBox.Show("Error, a group with that name already exists.");
            }
        }

        private void ContentTypeButton_New_Click(object sender, RoutedEventArgs e)
        {
            AddContentType();
        }

        private void ContentTypeButton_Rename_Click(object sender, RoutedEventArgs e)
        {
            RenameContentType(SaveFile.contentTypes.GetContentTypeByName(GetSelectedContentType()));
        }

        private void ContentTypeButton_Delete_Click(object sender, RoutedEventArgs e)
        {
            DeleteContentType(SaveFile.contentTypes.GetContentTypeByName(GetSelectedContentType()));
        }

        private void ContentTypeChangedEvent(object sender, RoutedEventArgs e)
        {
            if (!changingContentTypes)
            {
                ContentTypeSave(SaveFile.contentTypes.GetContentTypeByName(GetSelectedContentType()));
            }
        }

        private void AddContentTypeGroupButton_Click(object sender, RoutedEventArgs e)
        {
            String newName = Prompt.Show("Enter the new group name.", "New Content Type Group");
            if (newName == null || newName.Length <= 0)
            {

            }
            else if (!SaveFile.ctGroupsList.Contains(newName))
            {
                SaveFile.ctGroupsList.Add(newName);
                SaveFile.contentTypes.GetContentTypeByName(GetSelectedContentType()).Group = newName;
                InitializeContentTypeGroupDropdown(newName);
                UpdateContentTypeFields(SaveFile.contentTypes.GetContentTypeByName(GetSelectedContentType()));
            }
            else
            {
                MessageBox.Show("Error, a group with that name already exists.");
            }
        }
        /*
         * END OF EVENT HOOKS
         */
        #endregion
        
        #region command functions
        /*
         *  START OF COMMAND FUNCTIONS
         */
        private void New()
        {
            //MessageBox.Show("new!");
            String title = Prompt.Show("Enter the name of the new project.", "New Project");
            if (title != null && title.Length > 0)
            {
                SaveFile.NewFile(title, "");
                ToggleProjectMenus();
                Title = SaveFile.WindowTitle;
                ContentTypesTab.IsEnabled = true;
                SiteColumnsTab.IsEnabled = true;
                ManagedMetaDataTab.IsEnabled = true;
                UpdateManagedMetaDataTermSetList();
                UpdateSiteColumnList();
                UpdateContentTypeList();

                InitLists();
            }
            else if (title == null)
            {

            }
            else
            {
                MessageBox.Show("Error. Project name must not be empty.");
            }
        }

        private void Open()
        {
            Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
            dlg.DefaultExt = "."+DataModel.Names.FileExtension;
            dlg.Filter = DataModel.Names.ExtensionName + " (*." + DataModel.Names.FileExtension + ")|*." + DataModel.Names.FileExtension + "|XML Files (*.xml)|*.xml";
            Nullable<bool> res = dlg.ShowDialog();
            if (res == true)
            {
                if (SaveFile.LoadFromFile(dlg.FileName))
                {
                    ToggleProjectMenus();
                    Title = SaveFile.WindowTitle;
                    ContentTypesTab.IsEnabled = true;
                    SiteColumnsTab.IsEnabled = true;
                    ManagedMetaDataTab.IsEnabled = true;

                    UpdateContentTypeList();

                    InitLists();
                    UpdateSiteColumnList();

                    ManagedMetaDataTermSetTermTree.IsEnabled = false;
                    UpdateManagedMetaDataTermSetList();
                }
                else
                {
                    MessageBox.Show("Error Loading save file. Check the log!");
                }
            }
        }

        private void Save()
        {
            try
            {
                SaveFile.SaveToFile(SaveFile.Path);
            }
            catch
            {
                SaveAs();
            }
        }

        private void SaveAs()
        {
            Microsoft.Win32.SaveFileDialog dlg = new Microsoft.Win32.SaveFileDialog();
            dlg.DefaultExt = "." + DataModel.Names.FileExtension;
            dlg.Filter = DataModel.Names.ExtensionName + " (*." + DataModel.Names.FileExtension + ")|*." + DataModel.Names.FileExtension;
            dlg.OverwritePrompt = true;
            Nullable<bool> res = dlg.ShowDialog();
            if (res == true)
            {
                SaveFile.SaveToFile(dlg.FileName);
                SaveFile.Path = dlg.FileName;
                Title = SaveFile.WindowTitle;
            }
        }

        private void RenameProject()
        {
            String title = Prompt.Show("Enter the new name of the project.", "Rename Project");
            if (title != null && title.Length > 0)
            {
                SaveFile.Title = title;
                Title = SaveFile.WindowTitle;
            }
            else if (title == null)
            {

            }
            else
            {
                MessageBox.Show("Error. Project name must not be empty.");
            }
        }

        private void GenerateReport()
        {
            SaveFile.GenerateExcelReport();
        }

        int recentExits = 0;
        private void Exit()
        {
            if (recentExits > 0)
            {
                return;
            }
            try
            {
                if (IsSaveChanged())
                {
                    MessageBoxResult res = MessageBox.Show("You have unsaved changes. Would you like to save these changes?", "Unsaved Changes Warning", MessageBoxButton.YesNoCancel);
                    recentExits++;
                    new NoArgDelegate(() => { System.Threading.Thread.Sleep(500); Dispatcher.BeginInvoke(new Action(() => { recentExits--; })); }).BeginInvoke(null, null);
                    if (res == MessageBoxResult.Yes)
                    {
                        //save, then shutdown.
                        Save();
                        Application.Current.Shutdown(0);
                    }
                    else if (res == MessageBoxResult.No)
                    {
                        //ignore changes and shutdown
                        Application.Current.Shutdown(0);
                    }
                    else if (res == MessageBoxResult.Cancel)
                    {
                        //do nothing, abort the exit
                    }
                }
                else
                {
                    //no pending changes, just shutdown
                    Application.Current.Shutdown(0);
                }
            }
            catch
            {
                Application.Current.Shutdown(0);
            }
        }

        private bool IsSaveChanged()
        {
            if (!ContentTypesTab.IsEnabled)
            {
                return false;
            }
            
            if (SaveFile.Path == null || SaveFile.Path == "")
            {
                return true;
            }
            String tempPath = "C:\\temp_temp.temp";
            SaveFile.SaveToFile(tempPath);
            bool res = FileCompare(SaveFile.Path, tempPath);
            System.IO.File.Delete(tempPath);
            if (res)
            {
                return false;
            }
            else
            {
                return true;
            }
            
        }
        #region FileCompare
        //Copy and pasted from: http://stackoverflow.com/questions/7931304/comparing-two-files-in-c-sharp
        
        // This method accepts two strings the represent two files to 
        // compare. A return value of 0 indicates that the contents of the files
        // are the same. A return value of any other value indicates that the 
        // files are not the same.
        private bool FileCompare(string file1, string file2)
        {
            int file1byte;
            int file2byte;
            System.IO.FileStream fs1;
            System.IO.FileStream fs2;

            // Determine if the same file was referenced two times.
            if (file1 == file2)
            {
                // Return true to indicate that the files are the same.
                return true;
            }

            // Open the two files.
            fs1 = new System.IO.FileStream(file1, System.IO.FileMode.Open, System.IO.FileAccess.Read);
            fs2 = new System.IO.FileStream(file2, System.IO.FileMode.Open, System.IO.FileAccess.Read);

            // Check the file sizes. If they are not the same, the files 
            // are not the same.
            if (fs1.Length != fs2.Length)
            {
                // Close the file
                fs1.Close();
                fs2.Close();

                // Return false to indicate files are different
                return false;
            }

            // Read and compare a byte from each file until either a
            // non-matching set of bytes is found or until the end of
            // file1 is reached.
            do
            {
                // Read one byte from each file.
                file1byte = fs1.ReadByte();
                file2byte = fs2.ReadByte();
            }
            while ((file1byte == file2byte) && (file1byte != -1));

            // Close the files.
            fs1.Close();
            fs2.Close();

            // Return the success of the comparison. "file1byte" is 
            // equal to "file2byte" at this point only if the files are 
            // the same.
            return ((file1byte - file2byte) == 0);
        }
#endregion

        private void ExpandAllTreeItems(TreeViewItem tvi)
        {
            tvi.IsExpanded = true;
            foreach (TreeViewItem tvi2 in tvi.Items)
            {
                ExpandAllTreeItems(tvi2);
            }
        }

        private void CollapseAllTreeItems(TreeViewItem tvi)
        {  
            foreach (TreeViewItem tvi2 in tvi.Items)
            {
                CollapseAllTreeItems(tvi2);
            }
            tvi.IsExpanded = false;
        }

        private void ToggleProjectMenus()
        {
            Menu_Save.IsEnabled = true;
            Menu_SaveAs.IsEnabled = true;
            Menu_Rename.IsEnabled = true;
            Menu_Report.IsEnabled = true;
            Menu_Project_Header.IsEnabled = true;
            //Menu_SharePoint.IsEnabled = true;
        }
        /*
         *  END OF COMMAND FUNCTIONS
         */
        #endregion

        #region MANAGED METADATA TAB FUNCTIONS
        private void AddTermSet()
        {
            String name = Prompt.Show("Enter the name for the new term set: ", "New Term Set Name");
            if (name == null || name.Length <= 0) 
            {
                
            }
            else if (SaveFile.termSets.Contains(name))
            {
                MessageBox.Show("There is already a term set with that name.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else
            {
                SaveFile.termSets.Add(new TermSet(name));
                CaptureTVIstates(SaveFile.termSets.GetTermSetByName(GetSelectedMetadataTermSet()));
                UpdateManagedMetaDataTermSetList();
                foreach (ListBoxItem lbi in ManagedMetaDataTermSetList.Items)
                {
                    if (((String)lbi.Content) == name) { lbi.IsSelected = true; } else { lbi.IsSelected = false; }
                }
                LoadManagedMetaDataTermTree();
                UpdateManaegedMetaDataTermSetButtons();
            }
        }

        private void RenameTermSet(TermSet ts)
        {
            String name = Prompt.Show("Enter the new name for the term set: ", "New Term Set Name", ts.Name);
            if (name == null || name.Length <= 0)
            {

            }
            else if (SaveFile.termSets.Contains(name))
            {
                MessageBox.Show("There is already a term set with that name.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else
            {
                ts.Name = name;
                CaptureTVIstates(ts);
                UpdateManagedMetaDataTermSetList();
                foreach (ListBoxItem lbi in ManagedMetaDataTermSetList.Items)
                {
                    if (((String)lbi.Content) == name) { lbi.IsSelected = true; } else { lbi.IsSelected = false; }
                }
                LoadManagedMetaDataTermTree();
                UpdateManaegedMetaDataTermSetButtons();
            }
        }

        private void DeleteTermSet(TermSet ts)
        {
            MessageBoxResult res1 = MessageBox.Show("Are you sure you want to delete the term set: " + ts.Name, "Delete Term Set Confirmation", MessageBoxButton.YesNo);
            if (res1 == MessageBoxResult.Yes)
            {
                if (ts.Count > 0)
                {
                    MessageBoxResult res2 = MessageBox.Show("The term set (" + ts.Name + ") is not empty, would you like to delete all it's child terms?", "Delete Term Set Children Confirmation", MessageBoxButton.YesNo);
                    if (res2 == MessageBoxResult.Yes)
                    {
                        //delete all child terms, then term set.
                        ts.DeleteAllChildTerms();
                        SaveFile.termSets.Remove(ts);
                    }
                }
                else
                {
                    SaveFile.termSets.Remove(ts);
                }
                UpdateSiteColumnAdditionalInfoMetadataTextBox();
                UpdateManagedMetaDataTermSetList();
            }
            else
            {

            }

        }

        public void UpdateManagedMetaDataTab()
        {
            UpdateManagedMetaDataTermSetList();
            LoadManagedMetaDataTermTree();
        }

        private string GetSelectedMetadataTermSet()
        {
            String selectedTermSetName = "";
            foreach (ListBoxItem item in ManagedMetaDataTermSetList.Items)
            {
                if (item.IsSelected)
                {
                    selectedTermSetName = (String)item.Content;
                }
            }

            return selectedTermSetName;
        }

        private void AddRootTerm(TermSet ts)
        {
            if (ts == null)
            {
                ts = SaveFile.termSets.GetTermSetByName(GetSelectedMetadataTermSet());
            }

            if (ts == null)
            {
                throw new Exception("Well.... I give up. How did you even get here? ts is STILL null!");
            }

            String name = Prompt.Show("Enter the name for the new term.", "New Term");
            if (name != null && name != "")
            {
                if (ts.Contains(name))
                {
                    MessageBox.Show("There is already a term with that name in this parent.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
                else
                {
                    ts.AddRootTerm(name);
                    CaptureTVIstates(ts);
                    LoadManagedMetaDataTermTree();
                }
            }
        }

        private void AddTerm(Term t)
        {
            String name = Prompt.Show("Enter the new name for the term.", "New Term");
            if (name != null)
            {
                if (t.Contains(name))
                {
                    MessageBox.Show("There is already a term with that name in this parent term.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
                else
                {
                    try 
                    { 
                        t.Add(name).IsExpanded = true;
                        CaptureTVIstates(t.GetContainingTermSet());
                        t.IsExpanded = true;
                        t.IsTaggable = false;
                        LoadManagedMetaDataTermTree();
                    }
                    catch 
                    {
                        MessageBox.Show("Error, could not add term.");
                    }                    
                }
            }
        }

        private void RenameTerm(Term t)
        {
            String name = Prompt.Show("Enter the new name for the term.", "New Term", t.Name);
            if (name != null && name != "")
            {
                if (t.Parent.Contains(name))
                {
                    MessageBox.Show("There is already a term with that name in this parent term.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
                else
                {
                    t.Name = name;
                    UpdateSiteColumnAdditionalInfoMetadataTextBox();
                    CaptureTVIstates(t.GetContainingTermSet());
                    LoadManagedMetaDataTermTree();
                }
            }
        }

        private void DeleteTerm(Term t)
        {
            MessageBoxResult res1 = MessageBox.Show("Are you sure you want to delete the term: " + t.Name, "Delete Term Confirmation", MessageBoxButton.YesNo);
            if (res1 == MessageBoxResult.Yes)
            {
                if (t.IsReferencedByASiteColumn())
                {
                    t.RemoveSitecolumnReferences();
                }

                if (t.hasChildren())
                {
                    MessageBoxResult res2 = MessageBox.Show("The term (" + t.Name + ") is not empty, would you like to delete all it's child terms?", "Delete Term Children Confirmation", MessageBoxButton.YesNo);
                    if (res2 == MessageBoxResult.Yes)
                    {
                        //delete all child terms, then term set.
                        t.DeleteAllChildTerms();
                        t.Parent.Remove(t);
                    }
                }
                else
                {
                    t.Parent.Remove(t);
                }
                CaptureTVIstates(t.GetContainingTermSet());
                LoadManagedMetaDataTermTree();
                UpdateSiteColumnAdditionalInfoMetadataTextBox();
            }
        }

        private void ToggleTaggable(Term t)
        {
            t.IsTaggable = !t.IsTaggable;
            CaptureTVIstates(t.GetContainingTermSet());
            LoadManagedMetaDataTermTree();
        }

        private void UpdateManaegedMetaDataTermSetButtons() {
            String selectedTermSetName = GetSelectedMetadataTermSet();

            if (SaveFile.termSets.Contains(selectedTermSetName))
            {
                ManagedMetaDataTermSetButton_Delete.IsEnabled = true;
                ManagedMetaDataTermSetButton_Rename.IsEnabled = true;
                ManagedMetaDataTermButton_NewRoot.IsEnabled = true;
                ManagedMetaDataTermButton_NewRoot.CommandParameter = SaveFile.termSets.GetTermSetByName(selectedTermSetName);
            }
            else
            {
                ManagedMetaDataTermSetButton_Delete.IsEnabled = false;
                ManagedMetaDataTermSetButton_Rename.IsEnabled = false;
                ManagedMetaDataTermButton_NewRoot.IsEnabled = false;
                ManagedMetaDataTermButton_NewRoot.CommandParameter = null;
            }
        }

        public void UpdateManagedMetaDataTermSetList() 
        {
            while(ManagedMetaDataTermSetList.Items.Count != 0)
            {
                ManagedMetaDataTermSetList.Items.RemoveAt(0);
            }

            foreach(TermSet termSet in SaveFile.termSets) {
                ListBoxItem item = new ListBoxItem();

                ContextMenu cMenu = new ContextMenu();

                MenuItem newTermSet = new MenuItem();
                newTermSet.Header = "Add Term Set";
                newTermSet.Command = CustomCommands.Commands.AddTermSetCommand;
                newTermSet.Icon = FindResource("newTermSetIcon");
                cMenu.Items.Add(newTermSet);

                MenuItem renameTermSet = new MenuItem();
                renameTermSet.Header = "Rename";
                renameTermSet.Command = CustomCommands.Commands.RenameTermSetCommand;
                renameTermSet.CommandParameter = termSet;
                renameTermSet.Icon = FindResource("editIcon");
                cMenu.Items.Add(renameTermSet);

                MenuItem deleteTermSet = new MenuItem();
                deleteTermSet.Header = "Delete";
                deleteTermSet.Command = CustomCommands.Commands.DeleteTermSetCommand;
                deleteTermSet.CommandParameter = termSet;
                deleteTermSet.Icon = FindResource("deleteIcon");
                cMenu.Items.Add(deleteTermSet);

                Separator sep = new Separator();
                cMenu.Items.Add(sep);

                MenuItem isOpenforCreation = new MenuItem();
                isOpenforCreation.IsCheckable = true;
                isOpenforCreation.IsChecked = termSet.IsOpenForTermCreation;
                Binding b = new Binding("IsOpenForTermCreation");
                isOpenforCreation.Checked += new RoutedEventHandler((Object o, RoutedEventArgs e) => { termSet.IsOpenForTermCreation = !termSet.IsOpenForTermCreation; });
                isOpenforCreation.Header = "Is open for term creation";
                cMenu.Items.Add(isOpenforCreation);
                

                MenuItem changeGroupForTermSet = new MenuItem();
                changeGroupForTermSet.Header = "Change Group";
                changeGroupForTermSet.Command = CustomCommands.Commands.ChangeGroupForTermSetCommand;
                changeGroupForTermSet.CommandParameter = termSet;
                changeGroupForTermSet.Icon = FindResource("editIcon");
                cMenu.Items.Add(changeGroupForTermSet);

                Separator sep2 = new Separator();
                cMenu.Items.Add(sep2);

                MenuItem manageAttributes = new MenuItem();
                manageAttributes.Header = "Manage Properties";
                manageAttributes.Command = CustomCommands.Commands.ManagePropertiesForTermSet;
                manageAttributes.CommandParameter = termSet;
                //changeGroupForTermSet.Icon = FindResource("editIcon");
                cMenu.Items.Add(manageAttributes);

                item.ContextMenu = cMenu;

                item.Content = termSet.Name;
                ManagedMetaDataTermSetList.Items.Add(item);
            }

            ManagedMetaDataTermSetList.Items.Refresh();
        }

        private void ChangeGroupForTermSetCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            TermSetGroupPicker tsgp = new TermSetGroupPicker((TermSet)e.Parameter);
            tsgp.Owner = this;
            tsgp.Show();
        }


        private void ManagePropertiesForTermSetCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            TermSetLabelAttributeManager tslam = new TermSetLabelAttributeManager((TermSet)e.Parameter);
            tslam.Owner = this;
            tslam.Show();
        }

        private void ManagePropertiesForTermCommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            TermLabelAttributeManager tlam = new TermLabelAttributeManager((Term)e.Parameter);
            tlam.Owner = this;
            tlam.Show();
        }

        public void LoadManagedMetaDataTermTree()
        {
            String selectedTermSetName = GetSelectedMetadataTermSet();

            if (SaveFile.termSets.Contains(selectedTermSetName))
            {
                ManagedMetaDataTermSetTermTree.IsEnabled = true;                

                TermSet ts = SaveFile.termSets.GetTermSetByName(selectedTermSetName);
                //if (tviList.ContainsKey(ts)) { CaptureTVIstates(ts); }
          
                tviList[ts] = new List<TreeViewItem>(); // out with the old, in with the new.

                foreach (Term t in ts)
                {
                    TreeViewItem item = new TreeViewItem();
                    PopulateTreeViewItemWithTerm(item, t);                    
                    tviList[ts].Add(item);
                }
                
                ManagedMetadataTermSetLabel.Content = selectedTermSetName + " terms: ";
                ManagedMetaDataTermSetTermTree.ItemsSource = tviList[ts];
            }
            else
            {
                ManagedMetaDataTermSetTermTree.ItemsSource = null;
                ManagedMetaDataTermSetTermTree.IsEnabled = false;
                ManagedMetadataTermSetLabel.Content = "No term set selected";
            }
        }

        private TreeViewItem PopulateTreeViewItemWithTerm(TreeViewItem item, Term t)
        {            
            item.Header = t.Name;
            item.Tag = t;
            item.IsExpanded = t.IsExpanded;
            item = AddTermContextMenu(item, t);
            item.FontStyle = (t.IsTaggable) ? FontStyles.Normal : FontStyles.Oblique;
            item.FontWeight = (t.IsTaggable) ? FontWeights.Bold : FontWeights.Normal;
            item.BorderThickness = new Thickness(2);
            item.Margin = item.BorderThickness;
            if ((t.IsReferencedByASiteColumn()))
            {
                item.BorderBrush = Brushes.LightBlue;
                item.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#FFD1ECF5"));
            }

            foreach (Term st in t)
            {
                TreeViewItem subItem = new TreeViewItem();
                subItem = PopulateTreeViewItemWithTerm(subItem, st);
                item.Items.Add(subItem);
            }
            return item;
        }

        private TreeViewItem AddTermContextMenu(TreeViewItem item, Term t)
        {
            ContextMenu cMenu = new ContextMenu();
            MenuItem cMenuHeader = new MenuItem();
            cMenuHeader.Header = "Term: " + t.Name;
            cMenuHeader.IsEnabled = false;
            cMenuHeader.Foreground = Brushes.DarkBlue;
            cMenuHeader.HorizontalContentAlignment = System.Windows.HorizontalAlignment.Center;
            cMenuHeader.FontWeight = FontWeights.Bold;
            cMenuHeader.Icon = FindResource("infoIcon");
            cMenu.Items.Add(cMenuHeader);

            Separator sep1 = new Separator();
            cMenu.Items.Add(sep1);

            MenuItem addTerm = new MenuItem();
            addTerm.Header = "Add child term";
            addTerm.Command = CustomCommands.Commands.AddTermCommand;
            addTerm.CommandParameter = t;
            addTerm.Icon = FindResource("plusIcon");
            cMenu.Items.Add(addTerm);

            MenuItem renameTerm = new MenuItem();
            renameTerm.Header = "Rename Term";
            renameTerm.Command = CustomCommands.Commands.RenameTermCommand;
            renameTerm.CommandParameter = t;
            renameTerm.Icon = FindResource("editIcon");
            cMenu.Items.Add(renameTerm);

            MenuItem deleteTerm = new MenuItem();
            deleteTerm.Header = "Delete Term";
            deleteTerm.Command = CustomCommands.Commands.DeleteTermCommand;
            deleteTerm.CommandParameter = t;
            deleteTerm.Icon = FindResource("deleteIcon");
            cMenu.Items.Add(deleteTerm);

            Separator sep2 = new Separator();
            cMenu.Items.Add(sep2);

            MenuItem taggableTerm = new MenuItem();
            taggableTerm.Header = "Term is taggable.";
            taggableTerm.IsCheckable = true;
            taggableTerm.IsChecked = t.IsTaggable;
            taggableTerm.Command = CustomCommands.Commands.ToggleTaggableCommand;
            taggableTerm.CommandParameter = t;
            taggableTerm.Icon = FindResource("tagIcon");
            cMenu.Items.Add(taggableTerm);

            Separator sep3 = new Separator();
            cMenu.Items.Add(sep3);

            MenuItem expandTerm = new MenuItem();
            expandTerm.Header = "Expand All Children";
            expandTerm.Command = CustomCommands.Commands.ExpandAllTreeItemCommand;
            expandTerm.CommandParameter = item;
            cMenu.Items.Add(expandTerm);

            MenuItem collapseTerm = new MenuItem();
            collapseTerm.Header = "Collapse All Children";
            collapseTerm.Command = CustomCommands.Commands.CollapseAllTreeItemCommand;
            collapseTerm.CommandParameter = item;
            cMenu.Items.Add(collapseTerm);

            Separator sep4 = new Separator();
            cMenu.Items.Add(sep4);

            MenuItem manageAttributes = new MenuItem();
            manageAttributes.Header = "Manage Properties and Labels";
            manageAttributes.Command = CustomCommands.Commands.ManagePropertiesForTerm;
            manageAttributes.CommandParameter = t;
            //changeGroupForTermSet.Icon = FindResource("editIcon");
            cMenu.Items.Add(manageAttributes);

            item.ContextMenu = cMenu;

            return item;
        }

        private void CaptureTVIstates(TermSet ts)
        {
            try
            {
                if (ts != null && tviList[ts] != null)
                {
                    foreach (TreeViewItem tvi in tviList[ts])
                    {
                        CaptureTVIstates(tvi);
                    }
                }
            }
            catch (Exception e)
            {
                Log.Append("CaptureTVIstates Exception: ").Append(e.Message).AppendLine();
            }
        }

        private void CaptureTVIstates(TreeViewItem tvi1)
        {
            ((Term)tvi1.Tag).IsExpanded = tvi1.IsExpanded;
            foreach (TreeViewItem tvi2 in tvi1.Items)
            {
                CaptureTVIstates(tvi2);
            }
        }

        private void ManagedMetaDataTermSetTermTree_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
        {
            try
            {
                Term t = ((Term)((TreeViewItem)e.NewValue).Tag);
                if (t != null)
                {
                    ManagedMetaDataTermButton_AddTerm.CommandParameter = t;
                    ManagedMetaDataTermButton_AddTerm.IsEnabled = true;

                    ManagedMetaDataTermButton_RenameTerm.CommandParameter = t;
                    ManagedMetaDataTermButton_RenameTerm.IsEnabled = true;

                    ManagedMetaDataTermButton_DeleteTerm.CommandParameter = t;
                    ManagedMetaDataTermButton_DeleteTerm.IsEnabled = true;
                }
                else
                {
                    ManagedMetaDataTermButton_AddTerm.IsEnabled = false;
                    ManagedMetaDataTermButton_RenameTerm.IsEnabled = false;
                    ManagedMetaDataTermButton_DeleteTerm.IsEnabled = false;
                }
            }
            catch (Exception ex)
            {
                Log.Append("ManagedMetaDataTermSetTermTree_SelectedItemChanged Exception: ").Append(ex.Message).AppendLine(); ;
            }
        }
        #endregion

        #region SITE COLUMN TAB FUNCTIONS
        private void InitializeSiteColumnTypeDropdown()
        {
            while (SiteColumnFormType.Items.Count > 0) { SiteColumnFormType.Items.RemoveAt(0); }
            
            foreach (SiteColumnType sct in SiteColumnType.Types)
            {
                ComboBoxItem cbi = new ComboBoxItem();
                cbi.Content = sct.LongName;
                cbi.Tag = sct;
                SiteColumnFormType.Items.Add(cbi);
            }
        }

        private void InitializeSiteColumnGroupDropdown(String selected = "")
        {
            while (SiteColumnFormGroup.Items.Count > 0) { SiteColumnFormGroup.Items.RemoveAt(0); }

            foreach (String s in SiteColumn.SiteColumnGroups)
            {
                ComboBoxItem cbi = new ComboBoxItem();
                cbi.Content = s;
                if (s == selected) { cbi.IsSelected = true; }
                SiteColumnFormGroup.Items.Add(cbi);
            }
        }

        private void AddSiteColumn()
        {
            String name = Prompt.Show("Enter the name for the new site column: ", "New Site Column Name");
            if (name == null || name.Length <= 0)
            {

            }
            else if (SaveFile.siteCols.Contains(SPNameConverter.convertFromDisplay(name)))
            {
                MessageBox.Show("There is already a site column with that name.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else
            {
                SaveFile.siteCols.Add(new SiteColumn(name, DataModel.SPNameConverter.convertFromDisplay(name)));
                UpdateSiteColumnList();
                foreach (ListBoxItem lbi in SiteColumnsList.Items)
                {
                    if (((String)lbi.Content) == name) { lbi.IsSelected = true; } else { lbi.IsSelected = false; }
                }
                UpdateSiteColumnFields(SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn()));
            }
        }

        private void RenameSiteColumn(SiteColumn sc)
        {
            String name = Prompt.Show("Enter the new name for the site column: ", "New Site Column Name", sc.Name);
            if (name == null || name.Length <= 0)
            {

            }
            else if (SaveFile.siteCols.Contains(name))
            {
                MessageBox.Show("There is already a site column with that name.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else
            {
                sc.Name = name;
                UpdateSiteColumnList();
                foreach (ListBoxItem lbi in SiteColumnsList.Items)
                {
                    if (((String)lbi.Content) == name) { lbi.IsSelected = true; } else { lbi.IsSelected = false; }
                }
                UpdateSiteColumnFields(SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn()));
            }
        }

        private void DeleteSiteColumn(SiteColumn sc)
        {
            String s = "";
            List<ContentType> usedInList = new List<ContentType>();
            foreach (ContentType ct in SaveFile.contentTypes)
            {
                if (ct.SCList.Contains(sc))
                {
                    usedInList.Add(ct);
                }
            } 
            if (usedInList.Count != 0) {
                s = "This site column is referenced in " + usedInList.Count + " Content Types.\n";
            }
            MessageBoxResult res1 = MessageBox.Show(s + "Are you sure you want to delete site column: " + sc.Name, "Delete Site Column Confirmation", MessageBoxButton.YesNo);

            if (res1 == MessageBoxResult.Yes)
            {
                foreach (ContentType ct in usedInList) {
                    ct.SCList.Remove(sc);
                }
                SaveFile.siteCols.Remove(sc);
                UpdateSiteColumnList();
                UpdateContentTypeList();
            }
        }

        public void UpdateSiteColumnList()
        {
            String selectedColumnStaticName = GetSelectedSiteColumn();
            while (SiteColumnsList.Items.Count > 0)
            {
                SiteColumnsList.Items.RemoveAt(0);
            }

            foreach (SiteColumn sc in SaveFile.siteCols)
            {
                ListViewItem lvi = new ListViewItem();
                lvi.Content = sc.Name;
                lvi.Tag = sc;
                lvi.IsSelected = sc.InternalName == selectedColumnStaticName;

                SiteColumnsList.Items.Add(lvi);
            }
            SiteColumnsList.Items.Refresh();
            UpdateSiteColumnFields(SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn()));
        }

        private string GetSelectedSiteColumn()
        {         
            foreach (ListViewItem lvi in SiteColumnsList.Items)
            {
                if (lvi.IsSelected) {
                    return ((DataModel.SiteColumn)lvi.Tag).InternalName;
                }
            }
            return "";
        }

        private void UpdateSiteColumnsListButtons() {
            String selectedSiteColumn = GetSelectedSiteColumn();
            if (SaveFile.siteCols.Contains(selectedSiteColumn)) {
                SiteColumn sc = SaveFile.siteCols.GetSiteColByName(selectedSiteColumn);
                SiteColumnsButton_Rename.CommandParameter = sc;
                SiteColumnsButton_Rename.IsEnabled = true;

                SiteColumnsButton_Delete.CommandParameter = sc;
                SiteColumnsButton_Delete.IsEnabled = true;
            } else {
                SiteColumnsButton_Rename.IsEnabled = false;
                SiteColumnsButton_Delete.IsEnabled = false;
            }            
        }

        private void UpdateSiteColumnFields(SiteColumn sc)
        {
            SiteColumnFormType.SelectedIndex = -1; //this will force the type change event to fire. 
            UpdateSiteColumnsListButtons();
            if (sc == null)
            {
                SiteColumnsLabel.Header = "No site column selected.";
                
                SiteColumnFormName.Text = "";
                SiteColumnFormName.IsEnabled = false;

                SiteColumnFormStaticName.Text = "";
                SiteColumnFormStaticName.IsEnabled = false;

                scRenameBtn.IsEnabled = false;

                SiteColumnFormType.SelectedIndex = -1; //Will make it look "blank"
                SiteColumnFormType.IsEnabled = false;

                SiteColumnFormGroup.SelectedIndex = -1;
                SiteColumnFormGroup.IsEnabled = false;

                SiteColumnFormRequired.IsChecked = false;
                SiteColumnFormRequired.IsEnabled = false;

                SiteColumnFormUnique.IsChecked = false;
                SiteColumnFormUnique.IsEnabled = false;

                SiteColumnFormDefaultValue.Text = "";
                SiteColumnFormDefaultValue.IsEnabled = false;

                SiteColumnFormSampleValue.Text = "";
                SiteColumnFormSampleValue.IsEnabled = false;

                SiteColumnFormDesc.Text = "";
                SiteColumnFormDesc.IsEnabled = false;

                AddSiteColumnGroupButton.IsEnabled = false;
            }
            else
            {
                SiteColumnsLabel.Header = sc.Name + " details: ";
                
                SiteColumnFormName.Text = sc.Name;
                SiteColumnFormName.IsEnabled = false;

                SiteColumnFormStaticName.Text = sc.InternalName;
                SiteColumnFormStaticName.IsEnabled = false;

                scRenameBtn.IsEnabled = true;

                foreach (ComboBoxItem cbi in SiteColumnFormType.Items)
                {
                    if (sc.Type.ShortName == "Lookup") { cbi.IsEnabled = false; } //because, really...
                    if (sc.Type.LongName == (String)cbi.Content) { cbi.IsSelected = true; }
                }
                SiteColumnFormType.IsEnabled = true;

                bool found = false;
                foreach (ComboBoxItem cbi in SiteColumnFormGroup.Items)
                {
                    if (sc.PutInto == (String)cbi.Content) { cbi.IsSelected = true; found = true; }
                }
                if (!found) { ComboBoxItem cbi = new ComboBoxItem(); cbi.Content = sc.PutInto; cbi.IsSelected = true; SiteColumnFormGroup.Items.Add(cbi); }
                SiteColumnFormGroup.IsEnabled = true;

                SiteColumnFormRequired.IsChecked = sc.Required;
                SiteColumnFormRequired.IsEnabled = true;

                SiteColumnFormUnique.IsChecked = sc.Unique;
                SiteColumnFormUnique.IsEnabled = true;

                SiteColumnFormDefaultValue.Text = sc.DefaultVal;
                SiteColumnFormDefaultValue.IsEnabled = true;

                SiteColumnFormSampleValue.Text = sc.SampleVal;
                SiteColumnFormSampleValue.IsEnabled = true;

                SiteColumnFormDesc.Text = sc.Desc;
                SiteColumnFormDesc.IsEnabled = true;

                AddSiteColumnGroupButton.IsEnabled = true;
            }
            UpdateSiteColumnAdditionalInfoMetadataTextBox();
        }

        private void SiteColsSave(SiteColumn sc) 
        {
            try
            {
                if (sc != null)
                {
                    sc.Name = SiteColumnFormName.Text;
                    sc.Type = (SiteColumnType)((ComboBoxItem)SiteColumnFormType.SelectedItem).Tag;
                    sc.Required = (bool)SiteColumnFormRequired.IsChecked;
                    sc.Unique = (bool)SiteColumnFormUnique.IsChecked;
                    sc.DefaultVal = SiteColumnFormDefaultValue.Text;
                    sc.SampleVal = SiteColumnFormSampleValue.Text;
                    sc.Desc = SiteColumnFormDesc.Text;
                    sc.PutInto = (String)((ComboBoxItem)SiteColumnFormGroup.SelectedItem).Content;
                }
                else
                {
                    Log.Append("SiteColsSave: sc was null.").AppendLine();
                }
            }
            catch (Exception ex)
            {
                Log.Append("SiteColsSave Exception: ").Append(ex.Message).AppendLine();
            }
        }

        public void UpdateSiteColumnAdditionalInfoMetadataTextBox()
        {
            try
            {
                TextBox tb = (TextBox)LogicalTreeHelper.FindLogicalNode(SiteColumnsTab, "termNameTextBox");

                tb.Text = ((TermSet)tb.Tag).Name;
                SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn()).Tag = tb.Tag;
            }
            catch (Exception ex)
            {
                try
                {
                    if (SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn()).Type == SiteColumnType.MANAGED_METADATA)
                    {
                        throw new Exception("Could not find \"termNameTextBox\" in the MMD site column.\n"+ex.Message);
                    }
                }
                catch { }
            }
        }
        #endregion

        #region CONTENT TYPE FUNCTIONS

        public void UpdateContentTypeTab(ContentType sc = null)
        {
            UpdateContentTypeList();
            if (sc != null)
            {
                foreach (ListBoxItem lbi in ContentTypeList.Items)
                {
                    if ((String)lbi.Content == sc.Name) { lbi.IsSelected = true; }
                }
            }
            //UpdateContentTypeFields(sc);
        }

        public void UpdateContentTypeList()
        {
            while (ContentTypeList.Items.Count > 0)
            {
                ContentTypeList.Items.RemoveAt(0);
            }

            foreach (ContentType ct in SaveFile.contentTypes)
            {
                ListViewItem lvi = new ListViewItem();
                lvi.Content = ct.Name;

                ContentTypeList.Items.Add(lvi);
            }
            ContentTypeList.Items.Refresh();
            UpdateContentTypeFields(SaveFile.contentTypes.GetContentTypeByName(GetSelectedContentType()));
        }

        private void InitializeContentTypeParentDropdown(String selected = "")
        {
            while (ContentTypeFormParent.Items.Count > 0) { ContentTypeFormParent.Items.RemoveAt(0); }

            //Add content types from the SPDump
            foreach (ContentType ct in SaveFile.SPDump_contentTypes)
            {
                ComboBoxItem cbi = new ComboBoxItem();
                cbi.Content = ct.Name;
                cbi.Tag = ct;
                if (ct.Name == selected) { cbi.IsSelected = true; }
                ContentTypeFormParent.Items.Add(cbi);
            }

            Separator sep1 = new Separator();
            sep1.IsEnabled = false;
            ContentTypeFormParent.Items.Add(sep1);

            //Add each current content type if it isn't a child already
            foreach (ContentType ct in SaveFile.contentTypes)
            {
                if (ct != SaveFile.contentTypes.GetContentTypeByName(GetSelectedContentType()) && !ct.IsDescendantOf(SaveFile.contentTypes.GetContentTypeByName(GetSelectedContentType())))
                {
                    ComboBoxItem cbi = new ComboBoxItem();
                    cbi.Content = ct.Name;
                    cbi.Tag = ct;
                    if (ct.Name == selected) { cbi.IsSelected = true; }
                    ContentTypeFormParent.Items.Add(cbi);
                }
            }
        }

        private void ContentTypeChangedEvent(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                DataModel.ContentType ct = SaveFile.contentTypes.GetContentTypeByName(GetSelectedContentType());

                ct.Parent = ((ContentType)((ComboBoxItem)((ComboBox)sender).SelectedItem).Tag);

                InheritedContentTypeSiteColumnsGrid.ItemsSource = ct.InheritedSCList;
            }
            catch //(Exception ex)
            {
                //Log.Append("ContentTypeChangedEvent exception: " + ex.Message).AppendLine();
            }
        }

        private void InitializeContentTypeGroupDropdown(String selected = "")
        {
            while (ContentTypeFormGroup.Items.Count > 0) { ContentTypeFormGroup.Items.RemoveAt(0); }

            foreach (String s in SaveFile.ctGroupsList)
            {
                ComboBoxItem cbi = new ComboBoxItem();
                cbi.Content = s;
                if (s == selected) { cbi.IsSelected = true; }
                ContentTypeFormGroup.Items.Add(cbi);
            }
        }

        private void ContentTypeGroupChangedEvent(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                SaveFile.contentTypes.GetContentTypeByName(GetSelectedContentType()).Group = ((ComboBoxItem)((ComboBox)sender).SelectedItem).Content.ToString();
            }
            catch //(Exception ex)
            {
                //Log.Append("ContentTypeGroupChangedEvent exception: " + ex.Message).AppendLine();
            }
        }

        private void UpdateContentTypeFields(ContentType ct)
        {
            if (SaveFile.contentTypes.Contains(ct))
            {
                //enable UI elements and set fields to ct values
                ContentTypeFormName.Text = ct.Name;
                ContentTypeFormName.IsEnabled = false; //force them to use the rename button

                InitializeContentTypeParentDropdown();
                foreach (object o in ContentTypeFormParent.Items)
                {
                    try
                    {
                        ComboBoxItem cbi = o as ComboBoxItem;
                        if (ct.Parent.Name == (String)cbi.Content) { cbi.IsSelected = true; }
                    }
                    catch //(Exception ex)
                    {
                        //Log.Append("UpdateContentTypeFields exception: " + ex.Message).AppendLine(); // this was probaly caused by invalid casting a seperator to a comboboxitem
                    }
                }
                ContentTypeFormParent.IsEnabled = true;

                foreach (ComboBoxItem cbi in ContentTypeFormGroup.Items)
                {
                    if (ct.Group == (String)cbi.Content) { cbi.IsSelected = true; }
                }
                ContentTypeFormGroup.IsEnabled = true;

                ContentTypeFormNotes.Text = ct.Notes;
                ContentTypeFormNotes.IsEnabled = true;

                ContentTypeFormApproved.IsChecked = ct.IsApproved;
                ContentTypeFormApproved.IsEnabled = true;

                InheritedContentTypeSiteColumnsGrid.ItemsSource = ct.InheritedSCList;
                InheritedContentTypeSiteColumnsGrid.IsEnabled = true;

                ContentTypeSiteColumnsGrid.ItemsSource = ct.SCList;
                ContentTypeSiteColumnsGrid.IsEnabled = true;

                AddContentTypeButton.IsEnabled = true;
                ContentTypeButton_Rename.IsEnabled = true;
                ContentTypeButton_Delete.IsEnabled = true;
                ContentTypeFormSiteColumnButton.IsEnabled = true;
                ContentTypeFormNewSiteColumnButton.IsEnabled = true;
            }
            else
            {
                //disable UI elements
                //clear fields of values
                ContentTypeFormName.Text = "";
                ContentTypeFormName.IsEnabled = false;

                ContentTypeFormParent.SelectedIndex = -1;
                ContentTypeFormParent.IsEnabled = false;

                ContentTypeFormGroup.SelectedIndex = -1;
                ContentTypeFormGroup.IsEnabled = false;

                ContentTypeFormNotes.Text = "";
                ContentTypeFormNotes.IsEnabled = false;

                ContentTypeFormApproved.IsChecked = false;
                ContentTypeFormApproved.IsEnabled = false;

                InheritedContentTypeSiteColumnsGrid.ItemsSource = null;
                InheritedContentTypeSiteColumnsGrid.IsEnabled = true;

                ContentTypeSiteColumnsGrid.ItemsSource = null;
                ContentTypeSiteColumnsGrid.IsEnabled = false;

                AddContentTypeButton.IsEnabled = false;
                ContentTypeButton_Rename.IsEnabled = false;
                ContentTypeButton_Delete.IsEnabled = false;
                ContentTypeFormSiteColumnButton.IsEnabled = false;
                ContentTypeFormNewSiteColumnButton.IsEnabled = false;
            }
        }

        private String GetSelectedContentType()
        {
            String selected = "";
            try
            {
                foreach (ListViewItem lvi in ContentTypeList.Items)
                {
                    if (lvi.IsSelected)
                    {
                        selected = lvi.Content.ToString();
                    }
                }
            }
            catch (Exception e)
            {
                Log.Append("GetSelectedContentType Exception: ").Append(e.Message).AppendLine();
            }
            return selected;
        }

        private void AddContentType()
        {
            String name = Prompt.Show("Enter the name for the new content type: ", "New Content Type Name");
            if (name == null || name.Length <= 0)
            {

            }
            else if (SaveFile.contentTypes.Contains(name))
            {
                MessageBox.Show("There is already a content type with that name.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else if (DataModel.ContentType.ValidName(name) != "")
            {
                MessageBox.Show("The content type name '" + name + "' cannot contain: \\  / : * ? \" # % < > { } | ~ & , two consecutive periods (..), or special characters such as a tab.\n'" + DataModel.ContentType.ValidName(name) + "' was found.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else if (name.EndsWith("."))
            {
                MessageBox.Show("Name cannot end with a period.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else
            {
                SaveFile.contentTypes.Add(new ContentType(name));
                UpdateContentTypeList();
                foreach (ListBoxItem lbi in ContentTypeList.Items)
                {
                    if (((String)lbi.Content) == name) { lbi.IsSelected = true; } else { lbi.IsSelected = false; }
                }
                UpdateContentTypeFields(SaveFile.contentTypes.GetContentTypeByName(GetSelectedContentType()));
            }
        }

        private void RenameContentType(ContentType ct)
        {
            String name = Prompt.Show("Enter the new name for the content type: ", "New Content Type Name", ct.Name);
            if (name == null || name.Length <= 0)
            {

            }
            else if (SaveFile.contentTypes.Contains(name))
            {
                MessageBox.Show("There is already a content type with that name.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else if (DataModel.ContentType.ValidName(name) != "")
            {
                MessageBox.Show("The content type name '" + name + "' cannot contain: \\  / : * ? \" # % < > { } | ~ & , two consecutive periods (..), or special characters such as a tab.\n'" + DataModel.ContentType.ValidName(name)+"' was found.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else if (name.EndsWith("."))
            {
                MessageBox.Show("Name cannot end with a period.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else
            {
                ct.Name = name;
                UpdateContentTypeList();
                foreach (ListBoxItem lbi in ContentTypeList.Items)
                {
                    if (((String)lbi.Content) == name) { lbi.IsSelected = true; } else { lbi.IsSelected = false; }
                }
                UpdateContentTypeFields(SaveFile.contentTypes.GetContentTypeByName(GetSelectedContentType()));
            }
        }

        private void DeleteContentType(ContentType ct)
        {
            MessageBoxResult res1 = MessageBox.Show("Are you sure you want to delete content type: " + ct.Name, "Delete Content Type Confirmation", MessageBoxButton.YesNo);
            if (res1 == MessageBoxResult.Yes)
            {
                SaveFile.contentTypes.Remove(ct);
                UpdateContentTypeList();
            }
        }

        private void ContentTypeSave(ContentType ct)
        {
            try
            {
                if (ct != null)
                {
                    ct.Name = ContentTypeFormName.Text;
                    ct.Notes = ContentTypeFormNotes.Text;
                    ct.Group = (String)((ComboBoxItem)ContentTypeFormGroup.SelectedItem).Content;
                    ct.IsApproved = (bool)ContentTypeFormApproved.IsChecked;
                }
                else
                {
                    Log.Append("ContentTypeSave: ct was null.").AppendLine();
                }
            }
            catch (Exception ex)
            {
                Log.Append("ContentTypeSave Exception: ").Append(ex.Message).AppendLine();
            }
        }

        private void RemoveContentTypeColumn(object sender, RoutedEventArgs e)
        {
            ContentType ct = SaveFile.contentTypes.GetContentTypeByName(GetSelectedContentType());
            SiteColumn sc = ((FrameworkElement)sender).DataContext as SiteColumn;
            ct.SCList.Remove(sc);
            ContentTypeSiteColumnsGrid.ItemsSource = null;
            ContentTypeSiteColumnsGrid.ItemsSource = ct.SCList;
        }

        private void ContentTypeAddSiteColumn_Click(object sender, RoutedEventArgs e)
        {
            ContentType ct = SaveFile.contentTypes.GetContentTypeByName(GetSelectedContentType());
            
            SiteColumnPicker scp = new SiteColumnPicker(ct);
            scp.Owner = this;
            scp.ShowDialog();
        }

        private void ContentTypeAddSPSiteColumn_Click(object sender, RoutedEventArgs e)
        {
            ContentType ct = SaveFile.contentTypes.GetContentTypeByName(GetSelectedContentType());

            SiteColumnPicker scp = new SiteColumnPicker(ct, true);
            scp.Owner = this;
            scp.ShowDialog();
        }

        private void ContentTypeAddNewSiteColumn_Click(object sender, RoutedEventArgs e)
        {
            String name = Prompt.Show("Enter the name for the new site column: ", "New Site Column Name");
            if (name == null || name.Length <= 0)
            {

            }
            else if (SaveFile.siteCols.Contains(name))
            {
                MessageBox.Show("There is already a site column with that name.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            else
            {
                SiteColumn sc = new SiteColumn(name, DataModel.SPNameConverter.convertFromDisplay(name));
                ContentType ct = SaveFile.contentTypes.GetContentTypeByName(GetSelectedContentType());
                SaveFile.siteCols.Add(sc);
                ct.SCList.Add(sc);
                UpdateContentTypeTab(ct);
                ContentTypesTab.IsSelected = false;
                SiteColumnsTab.IsSelected = true;
                UpdateSiteColumnList();
                foreach (ListBoxItem lbi in SiteColumnsList.Items)
                {
                    if (((String)lbi.Content) == name) { lbi.IsSelected = true; } else { lbi.IsSelected = false; }
                }
                UpdateSiteColumnFields(SaveFile.siteCols.GetSiteColByName(GetSelectedSiteColumn()));
            }
        }
        #endregion

        

        

        
    }
}